package com.maizhi.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.maizhi.dao.BaseDaoI;
import com.maizhi.httpmodel.EasyuiTreeNode;
import com.maizhi.httpmodel.RoleModel;

import com.maizhi.model.Resource;
import com.maizhi.model.Role;
import com.maizhi.model.RoleResource;
import com.maizhi.model.UserRole;
import com.maizhi.service.RoleServiceI;
import com.maizhi.util.RoleComparator;


@Service("roleService")
public class RoleServiceImpl extends BaseServiceImpl<Role> implements
		RoleServiceI {

	private static final Logger logger = Logger.getLogger(RoleServiceImpl.class);

	private BaseDaoI<Role> roleDao;
	private BaseDaoI<RoleResource> roleResourceDao;
	private BaseDaoI<UserRole> userRoleDao;
	private BaseDaoI<Resource> resourceDao;

	public BaseDaoI<Resource> getResourcesDao() {
		return resourceDao;
	}

	@Autowired
	@Qualifier("resourceDao")
	public void setResourcesDao(BaseDaoI<Resource> resourceDao) {
		this.resourceDao = resourceDao;
	}

	public BaseDaoI<Role> getRoleDao() {
		return roleDao;
	}

	@Autowired
	@Qualifier("roleDao")
	public void setRoleDao(BaseDaoI<Role> roleDao) {
		this.roleDao = roleDao;
	}

	public BaseDaoI<RoleResource> getRoleResourceDao() {
		return roleResourceDao;
	}

	@Autowired
	@Qualifier("roleResourceDao")
	public void setRoleResourceDao(BaseDaoI<RoleResource> roleResourceDao) {
		this.roleResourceDao = roleResourceDao;
	}

	public BaseDaoI<UserRole> getUserRoleDao() {
		return userRoleDao;
	}

	@Autowired
	@Qualifier("userRoleDao")
	public void setUserRoleDao(BaseDaoI<UserRole> userRoleDao) {
		this.userRoleDao = userRoleDao;
	}


	@Cacheable(value = "RoleCache", key = "'tree'+#id")
	@Transactional(readOnly = true)
	public List<EasyuiTreeNode> tree(String id) {
		String hql = "from Role t where t.role is null order by t.seq";
		if (id != null && !id.trim().equals("")) {
			hql = "from Role t where t.role.id ='" + id + "' order by t.seq";
		}
		List<Role> syroleList = roleDao.find(hql);
		List<EasyuiTreeNode> tree = new ArrayList<EasyuiTreeNode>();
		for (Role syrole : syroleList) {
			tree.add(tree(syrole, false));
		}
		return tree;
	}

	private EasyuiTreeNode tree(Role role, boolean recursive) {
		EasyuiTreeNode node = new EasyuiTreeNode();
		node.setId(role.getId());
		node.setText(role.getText());
		Map<String, Object> attributes = new HashMap<String, Object>();
		node.setAttributes(attributes);
		if (role.getRoles() != null && role.getRoles().size() > 0) {
			node.setState("closed");
			if (recursive) {// 递归查询子节点
				List<Role> syroleList = new ArrayList<Role>(role.getRoles());
				Collections.sort(syroleList, new RoleComparator());// 排序
				List<EasyuiTreeNode> children = new ArrayList<EasyuiTreeNode>();
				for (Role r : syroleList) {
					EasyuiTreeNode t = tree(r, true);
					children.add(t);
				}
				node.setChildren(children);
			}
		}
		return node;
	}

	@Cacheable(value = "RoleCache", key = "'treegrid'+#id")
	@Transactional(readOnly = true)
	public List<RoleModel> treegrid(String id) {
		List<RoleModel> treegrid = new ArrayList<RoleModel>();
		String hql = "from Role t where t.role is null order by t.seq";
		if (id != null && !id.trim().equals("")) {
			hql = "from Role t where t.role.id = '" + id + "' order by t.seq";
		}
		List<Role> syroleList = roleDao.find(hql);
		for (Role syrole : syroleList) {
			RoleModel r = new RoleModel();
			BeanUtils.copyProperties(syrole, r);
			if (syrole.getRole() != null) {
				r.setParentId(syrole.getRole().getId());
				r.setParentText(syrole.getRole().getText());
			}
			if (syrole.getRoles() != null && syrole.getRoles().size() > 0) {
				r.setState("closed");
			}
			if (syrole.getRoleResources() != null && syrole.getRoleResources().size() > 0) {
				String resourcesTextList = "";
				String resourcesIdList = "";
				boolean b = false;
				Set<RoleResource> syroleSyresourcesSet = syrole.getRoleResources();
				for (RoleResource syroleSyresources : syroleSyresourcesSet) {
					Resource syresources = syroleSyresources.getResource();
					if (!b) {
						b = true;
					} else {
						resourcesTextList += ",";
						resourcesIdList += ",";
					}
					resourcesTextList += syresources.getText();
					resourcesIdList += syresources.getId();
				}
				r.setResourcesId(resourcesIdList);
				r.setResourcesText(resourcesTextList);
			}
			treegrid.add(r);
		}
		return treegrid;
	}

	@CacheEvict(value = "RoleCache", allEntries = true)
	public RoleModel add(RoleModel r) {
		Role syrole = new Role();
		BeanUtils.copyProperties(r, syrole);
		if (r.getParentId() != null && !r.getParentId().trim().equals("")) {
			syrole.setRole(roleDao.load(Role.class, r.getParentId()));
		}
		roleDao.save(syrole);
		return r;
	}

	@CacheEvict(value = "RoleCache", allEntries = true)
	public void del(RoleModel r) {
		Role syrole = roleDao.get(Role.class, r.getId());
		if (r != null) {
			recursiveDelete(syrole);
		}
	}

	private void recursiveDelete(Role syrole) {
		if (syrole.getRoles() != null && syrole.getRoles().size() > 0) {
			Set<Role> syroleSet = syrole.getRoles();
			for (Role t : syroleSet) {
				recursiveDelete(t);
			}
		}

		List<RoleResource> syroleSyresourcesList = roleResourceDao.find("from RoleResource t where t.role=?", syrole);
		if (syroleSyresourcesList != null && syroleSyresourcesList.size() > 0) {
			for (RoleResource syroleSyresources : syroleSyresourcesList) {
				roleResourceDao.delete(syroleSyresources);
			}
		}

		List<UserRole> syuserSyroleList = userRoleDao.find("from UserRole t where t.role=?", syrole);
		if (syuserSyroleList != null && syuserSyroleList.size() > 0) {
			for (UserRole syuserSyrole : syuserSyroleList) {
				userRoleDao.delete(syuserSyrole);
			}
		}

		roleDao.delete(syrole);
	}

	@CacheEvict(value = "RoleCache", allEntries = true)
	public RoleModel edit(RoleModel r) {
		Role syrole = roleDao.get(Role.class, r.getId());
		if (syrole != null) {
			BeanUtils.copyProperties(r, syrole);
			if (!syrole.getId().equals("0")) {// 跟节点不可以修改上级节点
				syrole.setRole(roleDao.get(Role.class, r.getParentId()));
			}

			List<RoleResource> syroleSyresourcesList = roleResourceDao.find("from RoleResource t where t.role=?", syrole);
			for (RoleResource syroleSyresources : syroleSyresourcesList) {
				roleResourceDao.delete(syroleSyresources);
			}

			if (r.getResourcesId() != null && !r.getResourcesId().equals("")) {// 保存角色和资源的关系
				String[] resourceIds = r.getResourcesId().split(",");
				for (String resourceId : resourceIds) {
					RoleResource syroleSyresources = new RoleResource();// 关系
					Resource syresources = resourceDao.get(Resource.class, resourceId);// 资源
					syroleSyresources.setId(UUID.randomUUID().toString());
					syroleSyresources.setRole(syrole);
					syroleSyresources.setResource(syresources);
					roleResourceDao.save(syroleSyresources);
				}
			}
		}
		return r;
	}

	
}
